#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

char historyfile[512];
int sock = -1;


void signal(int signum)
{
	write_history(historyfile);
	exit(0);
}

void gotLine(char *line)
{
	if(line == NULL) exit(0);
	if(strlen(line) == 0) return;
	add_history(line);
	size_t len = strlen(line);
	line[len] = '\n';
	write(sock, line, len+1);
}

void connectsock()
{
	struct sockaddr_un sa;
	sa.sun_family = AF_UNIX;
	strncpy(sa.sun_path, "./console.socket",
		(sizeof(struct sockaddr_un) - sizeof(short)));
		
	if ((sock = socket( AF_UNIX, SOCK_STREAM, 0)) == -1) {
		perror("Failed to create socket");
		exit(1);
	}
	
	if ((connect(sock, (sockaddr *)&sa, sizeof(struct sockaddr_un))) == - 1) {
		perror("Failed to connect to server");
		exit(1);
	}
}

void help()
{
	fprintf(stderr,"Usage: smpadmin-console [OPTIONS] \n\
\t-h --help\tShow this help text \n\
\t-c command\tRun Command\n");
}

int main(int argc, char **argv)
{
	if(argc >= 2)
	{
		if((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0))
		{
			help();
			exit(0);
		}
		else if(strcmp(argv[1], "-c") == 0)
		{
			if(argc < 3)
			{
				fprintf(stderr,"You must specify a command to run.\n");
				exit(1);
			}
		}
		else
		{
			help();
			exit(1);
		}
	}
	
	connectsock();
	
	FILE *infile = fdopen(sock, "r");
	if(infile == NULL)
	{
		fprintf(stderr,"Failed to get file pointer for input stream\n");
		return(1);
	}

	signal(SIGTERM,signal);
	signal(SIGINT,signal);
	signal(SIGHUP,signal);
	
	
	if(argc >= 2)
	{
		if(strcmp(argv[1], "-c") == 0)
		{	
			char buf[1024];
			buf[0] = '\0';
			
			for(int i = 2; i < argc; i++)
			{
				strncat(buf,argv[i],1023-strlen(buf));
				strncat(buf," ",1023-strlen(buf));
			}
			
			strncat(buf,"\n",1023-strlen(buf));
			
			printf("CMD: %s", buf);
			
			write(sock, buf, strlen(buf));
			
			exit(0);
		}
	}
	
	
	snprintf(historyfile, 512, "%s/.smpadmin-history",getenv("HOME"));
	
	using_history();
	read_history(historyfile);
	rl_bind_keyseq("\\M-[B",rl_get_next_history);
	rl_bind_keyseq("\\M-[A",rl_get_previous_history);
	rl_callback_handler_install("SMPAdmin# ", gotLine);
	
	fd_set readset;
	
	int result = -1;
	char buf[1024];
	int readsize;
	
	do
	{
		FD_ZERO(&readset);
		FD_SET(sock,&readset);
		FD_SET(0,&readset);
		
		 result = select(sock+1, &readset, NULL, NULL, NULL);
		 
		 if(FD_ISSET(sock, &readset))
		 {
			fgets(buf,1024,infile);
			
			printf("\r%s", buf);					

			rl_on_new_line();
			rl_redisplay();
		 }
		 
		 if(FD_ISSET(0, &readset))
		 {
			rl_callback_read_char();
		 }
		 
	} while(result != -1);
	
	//if we get here, something is wrong
	fprintf(stderr,"Failed to read pipe: %s\n",strerror(errno));
	
	return(0);
}
